package pl.skubicha.service;

import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.jboss.logging.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import pl.skubicha.domain.CreditingForm;
import pl.skubicha.exceptions.CreditingFormNotFoundException;
import pl.skubicha.exceptions.EntityConstraintException;
import pl.skubicha.repository.CreditingFormRepository;
import pl.skubicha.response.CreditingFormDTO;
import pl.skubicha.utils.CreditingFormMapper;

@Service
public class CreditingFormRepositoryService implements CreditingFormService {

	private static Logger logger = Logger.getLogger( CreditingFormRepositoryService.class );

	@Resource
	private CreditingFormRepository formRepository;

	@Transactional( readOnly = true )
	@Override
	public List< CreditingForm > findAll() {
		logger.debug( "Pobieram wszystkie formy zaliczenia" );
		return formRepository.findAll();
	}

	@Transactional( readOnly = true )
	@Override
	public CreditingForm findById( final Integer id ) throws CreditingFormNotFoundException {

		logger.debug( "Wyszukuję formę zaliczenia o id: " + id );

		final CreditingForm form = formRepository.findOne( id );

		if ( form == null ) {
			logger.debug( "Nie znaleziono formy zaliczenia o id: " + id );
			throw new CreditingFormNotFoundException( "Nie znaleziono formy zaliczenia o id: " + id );
		}

		return form;
	}

	@Override
	@Transactional
	public CreditingForm create( final CreditingFormDTO created ) {
		final CreditingForm form = CreditingFormMapper.map( created );
		return formRepository.save( form );
	}

	@Override
	@Transactional( rollbackFor = CreditingFormNotFoundException.class )
	public CreditingForm update( final CreditingFormDTO updated ) throws CreditingFormNotFoundException {

		final CreditingForm form = formRepository.findOne( updated.getId() );

		if ( form == null ) {
			throw new CreditingFormNotFoundException( "Nie znaleziono formy zaliczenia o id: " + updated.getId() );
		}

		form.update( updated.getName(), updated.getPartialGrades(), updated.getFinalGrades() );

		return form;
	}

	@Override
	@Transactional( rollbackFor = CreditingFormNotFoundException.class )
	public CreditingForm delete( final Integer id ) throws CreditingFormNotFoundException, EntityConstraintException {

		final CreditingForm deleted = formRepository.findOne( id );

		if ( deleted == null ) {
			throw new CreditingFormNotFoundException( "Nie znaleziono formy zaliczenia o id: " + id );
		}

		if ( CollectionUtils.isNotEmpty( deleted.getPartialGrades() ) ) {
			throw new EntityConstraintException( "Forma zaliczenia " + deleted.getName() + " posiada referencje do przedmiotów!" );
		}

		if ( CollectionUtils.isNotEmpty( deleted.getFinalGrades() ) ) {
			throw new EntityConstraintException( "Forma zaliczenia " + deleted.getName() + " posiada referencje do studentów!" );
		}

		formRepository.delete( deleted );
		return deleted;
	}

	public void setCreditingFormRepository( final CreditingFormRepository formRepository ) {
		this.formRepository = formRepository;
	}

}